package com.tuyrt.hi.library.restful

import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import java.util.concurrent.ConcurrentHashMap

/**
 * author: Administrator on 2021/6/23.
 * desc:
 */
class HiRestful constructor(val baseUrl: String, callFactory: HiCall.Factory) {

    private val interceptors: MutableList<HiInterceptor> = mutableListOf()

    // 每个方法可能多次调用，需要缓存 MethodParser
    private var methodService: ConcurrentHashMap<Method, MethodParser> = ConcurrentHashMap()
    private var scheduler: Scheduler

    init {
        scheduler = Scheduler(callFactory, interceptors)
    }

    fun addInterceptor(interceptor: HiInterceptor) {
        interceptors.add(interceptor)
    }

    /**
     * interface ApiService {
     *  @Headers("auth-token:token", "accountId:123456")
     *  @BaseUrl("https://api.devio.org/as/")
     *  @POST("/cities/{province}")
     *  @GET("/cities")
     * fun listCities(@Path("province") province: Int,@Filed("page") page: Int): HiCall<JsonObject>
     * }
     */
    fun <T> create(service: Class<T>): T {
        return Proxy.newProxyInstance(service.classLoader, arrayOf<Class<*>>(service), object : InvocationHandler {
            //bugFix:此处需要考虑 空参数
            override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any {
                var methodParser = methodService.get(method)
                if (methodParser == null) {
                    methodParser = MethodParser.parse(baseUrl, method)
                    methodService[method] = methodParser
                }

                // bugFix: 此处应该考虑到 methodParrse服用，每次调用都应当解析入参
                val request = methodParser.newRequest(method, args)
                return scheduler.newCall(request)
            }
        }) as T
    }

}